module ws2812_ctrl (
	input 	wire		sys_clk,
	input 	wire		sys_rst_n,
	input 	wire		bit,
	output 	wire		dout,
	output 	reg 	[4:0] 	cnt_bit,//哪一bit
	output 	reg 	[6:0] 	cnt_led,//64个灯中哪个灯
	output reg      [2:0]	cnt_photo
);

parameter 	T0H = 5'd15	,
	  	T0L = 6'd40	,
		T1H = 6'd40	,
		T1L = 5'd40	,
		RST = 25'd25000000 ;


reg [5:0] cnt_0;//计58个比特0计数器
wire   add_cnt0;
wire   end_cnt0;


reg [6:0] cnt_1;//计80个比特1计数器
wire   add_cnt1;
wire   end_cnt1;

//reg [4:0] cnt_bit;//计24个bit刷新计数器
wire   add_cnt_bit;
wire   end_cnt_bit;

//reg [6:0] cnt_led;//计8*8=64个led点阵点亮计数器
wire   add_cnt_led;
wire   end_cnt_led;

reg [24:0] cnt_rst;//复位计数器300us
wire   add_cnt_rst;
wire   end_cnt_rst;

reg 	flag_rst;

always @(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)begin
		cnt_0 <= 6'd0;
	end
	else if(add_cnt0)begin

		if(end_cnt0)begin
			cnt_0 <= 0;
		end
		else begin
			cnt_0 <= cnt_0 + 6'd1;
		end
	end
	else begin
		cnt_0 <= 6'd0;
	end
end

assign add_cnt0 = ~bit && flag_rst ==0;
assign end_cnt0 = add_cnt0 && (cnt_0 == T0H + T0L - 1);//有这个add_cnt0才能进循环

always @(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)begin
		cnt_1 <= 7'd0;
	end
	else if(add_cnt1)begin
		if(end_cnt1)begin
			cnt_1 <= 7'd0;
		end
		else begin
			cnt_1 <= cnt_1 + 7'd1;
		end
	end
	else begin
		cnt_1 <= 7'd0;
	end
end


assign add_cnt1 = bit && flag_rst ==0;
assign end_cnt1 = add_cnt1 && (cnt_1 == T1H + T1L - 1);

always @(posedge sys_clk or negedge sys_rst_n) begin
	if(!sys_rst_n) begin
		cnt_bit <= 5'd0;
	end
	else if(add_cnt_bit) begin
		if(end_cnt_bit) begin
			cnt_bit <= 5'd0;
		end
		else begin
			cnt_bit <= cnt_bit + 5'd1;
		end
	end
	else begin
		cnt_bit <= cnt_bit;
	end
	
end

assign add_cnt_bit =  end_cnt0 || end_cnt1;//0码或者1码发送完毕就加1
assign end_cnt_bit = add_cnt_bit &&(cnt_bit == 5'd24 - 1);//记24个

always @(posedge sys_clk or negedge sys_rst_n) begin
	if(!sys_rst_n) begin
		cnt_led <= 7'd0;
	end
	else if(add_cnt_led) begin
		if(end_cnt_led) begin
			cnt_led <= 7'd0;
		end
		else begin
			cnt_led <= cnt_led + 7'd1;
		end
	end
	else begin
		cnt_led <= cnt_led;
	end
end

assign add_cnt_led = end_cnt_bit;//一个灯
assign end_cnt_led = add_cnt_led && (cnt_led == 7'd64 - 1);//一共64个灯

always @(posedge sys_clk or negedge sys_rst_n) begin
	if(!sys_rst_n) begin
		cnt_rst <= 14'd0;
	end
	else if(add_cnt_rst) begin
		if(end_cnt_rst) begin
			cnt_rst <= 14'd0;
		end
		else begin
			cnt_rst <= cnt_rst + 14'd1;
		end
	end
	else begin
		cnt_rst <= 7'd0;
	end
end

assign add_cnt_rst = flag_rst;
assign end_cnt_rst = add_cnt_rst && (cnt_rst == RST - 1);

always @(posedge sys_clk or negedge sys_rst_n) begin
	if(!sys_rst_n) begin
		flag_rst <= 0;
	end
	else if(end_cnt_led) begin
		flag_rst <= 1;
	end
	else if(end_cnt_rst)begin
		flag_rst <= 0;
	end
	else begin
		flag_rst <= flag_rst;
	end
end


assign dout = (flag_rst == 0) ? (((bit == 0 && cnt_0 < T0H) ? 1'b1 : 1'b0) | ((bit == 1 && cnt_1< T1H) ? 1'b1 : 1'b0)): 1'b0;

//assign dout = (flag_rst == 0) ? ((( cnt_0 < T0H )? 1'b1 : 1'b0) | (( cnt_1< T1H) ? 1'b1 : 1'b0)): 1'b0;
always @(posedge sys_clk or negedge sys_rst_n) begin
	if(!sys_rst_n) begin
		cnt_photo <= 3'd0;
	end
	else if(end_cnt_led&& cnt_photo != 3'b100) begin
		cnt_photo <= cnt_photo + 3'd1;
	end
	else if(end_cnt_led&& cnt_photo == 3'b100) begin
		cnt_photo <= 3'd0;
	end
	else begin
		cnt_photo <= cnt_photo;
	end
end
endmodule